package com.wcpdoc.exam.core.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.wcpdoc.base.entity.User;
import com.wcpdoc.base.service.UserService;
import com.wcpdoc.core.dao.BaseDao;
import com.wcpdoc.core.entity.PageIn;
import com.wcpdoc.core.entity.PageOut;
import com.wcpdoc.core.entity.PageResult;
import com.wcpdoc.core.entity.PageResultEx;
import com.wcpdoc.core.exception.MyException;
import com.wcpdoc.core.service.impl.BaseServiceImp;
import com.wcpdoc.core.util.ValidateUtil;
import com.wcpdoc.exam.core.dao.ResourceDao;
import com.wcpdoc.exam.core.em.EmResourceType;
import com.wcpdoc.exam.core.entity.Resource;
import com.wcpdoc.exam.core.service.ResourceService;
import com.wcpdoc.exam.core.util.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class ResourceServiceImpl extends BaseServiceImp<Resource> implements ResourceService {


    @javax.annotation.Resource
    private ResourceDao resourceDao;
    @javax.annotation.Resource
    private UserService userService;

    @Override
    @javax.annotation.Resource(name = "resourceDaoImpl")
    public void setDao(BaseDao<Resource> dao) {
        super.dao = dao;
    }


    @Value("${sys.fileRoot}")
    private String fileRoot;
    @Value("${sys.fileRootUrl}")
    private String fileRootUrl;


    /**
     * 创建文件夹
     *
     * @param dirName
     * @Param parentId
     * @Param userId
     * @return
     */
    @Override
    public PageResult createDir(String dirName,Integer parentId,Integer userId) {
        if(!ValidateUtil.isValid(dirName)){
            return PageResult.err().msg("文件夹名称不能为空！");
        }
        dirName=dirName.trim();
        String resourceUrl= dirName;
        if(parentId!=-1){
            Resource resource = getEntity(parentId);
            if(resource==null){
                return PageResult.err().msg("父目录不存在！");
            }
            if (!resource.getIsFolder()) {
                return PageResult.err().msg("父目录不是文件夹！");
            }
            resourceUrl= Paths.get(resource.getResourceUrl(),dirName).toString();
        }
        //判断当前需要新建的文件夹是否存在
        int i1 = resourceDao.getCountBySelect(dirName,parentId,1);
        if(i1>0){
            return PageResult.err().msg("文件夹已存在！");
        }
        Resource infoResource = new Resource();
        infoResource.setParentId(parentId);
        infoResource.setResourceName(dirName);
        infoResource.setResourceUrl(resourceUrl);
        infoResource.setResourceSize(0);
        infoResource.setResourceType(EmResourceType.文件夹.getCode());
        infoResource.setDownloadCount(0);
        infoResource.setRemark(null);
        infoResource.setFileMd5(null);
        infoResource.setIsFolder(true);
        infoResource.setState(0);
        infoResource.setUpdateUserId(userId);
        infoResource.setUpdateTime(DateUtil.date());
        add(infoResource);

        Path path = Paths.get(fileRoot, resourceUrl).toAbsolutePath();
        if(!FileUtil.exists(path,false)){
            FileUtil.mkdir(path);
        }
        return PageResult.ok();
    }

    /**
     * 上传资源
     *
     * @param file
     * @param parentId
     * @return
     */
    @Override
    public PageResult upload(MultipartFile file, Integer parentId,Integer userId) {
        String ParentPath= StrUtil.EMPTY;
        if(parentId!=-1){
            Resource resource = getEntity(parentId);
            if(resource==null){
                return PageResult.err().msg("父目录不存在！");
            }
            if (!resource.getIsFolder()) {
                return PageResult.err().msg("父目录不是文件夹！");
            }
            ParentPath=resource.getResourceUrl();
        }
        if(file==null){
            return PageResult.err().msg("文件不能为空！");
        }
        int i1 = resourceDao.getCountBySelect(file.getOriginalFilename(),parentId,0);
        if(i1>0){
            return PageResult.err().msg("该文件已经存在！");
        }
        Resource infoResource = new Resource();
        infoResource.setParentId(parentId);
        infoResource.setResourceName(file.getOriginalFilename());
        infoResource.setResourceUrl(Paths.get(ParentPath,file.getOriginalFilename()).toString());
        infoResource.setResourceSize(Math.toIntExact(file.getSize()));
        infoResource.setResourceType(FileUtils.transforType(file.getOriginalFilename()));
        infoResource.setDownloadCount(0);
        infoResource.setRemark(null);
        infoResource.setFileMd5(null);
        infoResource.setIsFolder(false);
        infoResource.setState(0);
        infoResource.setUpdateUserId(userId);
        infoResource.setUpdateTime(DateUtil.date());
        add(infoResource);

        //上传文件
        String filePath = Paths.get(fileRoot,
                infoResource.getResourceUrl()
        ).toAbsolutePath().toString();
        FileUtils.storeFile(file,filePath);
        return PageResult.ok();
    }

    /**
     * 批量删除资源(可以是文件夹或者文件)
     *
     * @param id
     * @return
     */
    @Override
    public PageResult delete(Integer id,Integer userId) {
        Resource resource=getEntity(id);
        if(resource==null||resource.getState()!=0){
            return PageResult.err().msg("资源不存在！");
        }
        if(resource.getIsFolder()){
            //判断文件夹下面是否存在字文件
            Integer count= resourceDao.getCountByParentId(resource.getId());
            if(count>0){
                return PageResult.err().msg("文件夹下面存在文件或者文件夹,不能删除!");
            }
            //删除文件夹
            Path path = Paths.get(fileRoot, resource.getResourceUrl()).toAbsolutePath();
            if(FileUtil.exists(path,false)){
                FileUtil.del(path);
            }
        }else{
            //删除文件
            String filePath = Paths.get(fileRoot,
                    resource.getResourceUrl()
            ).toAbsolutePath().toString();
            FileUtil.del(filePath);
        }
        //删除自己
        resource.setState(1);
        resource.setUpdateTime(DateUtil.date());
        resource.setUpdateUserId(userId);
        update(resource);
        return PageResult.ok();
    }

    /**
     * 查询资源列表
     *
     * @param pageIn
     * @return
     */
    @Override
    public PageResult listResource(PageIn pageIn) {
        PageOut pageOut= dao.getListpage(pageIn);
        final List<Map<String, Object>> list = pageOut.getList();
        list.forEach(map -> {
            String httpUrl=StrUtil.EMPTY;
            if(map.get("isFolder").equals(false)) {
                final String resourceUrl = StrUtil.replace(map.get("resourceUrl").toString(), "\\", "/");
                httpUrl = fileRootUrl + resourceUrl;
            }
            map.put("httpUrl",httpUrl);
            map.put("updateTime", map.get("updateTime") == null ? null : com.wcpdoc.core.util.DateUtil.formatDateTime(com.wcpdoc.core.util.DateUtil.getDateTime( map.get("updateTime").toString())));
        });

        return PageResultEx.ok().data(pageOut);
    }

    /**
     * 上传头像
     *
     * @param file
     * @return
     */
    @Override
    public PageResult uploadAvatar(MultipartFile file, Integer userId) {
        if(file==null){
            return PageResult.err().msg("文件不能为空！");
        }
        try {
            User user = userService.getEntity(userId);
            Path path = Paths.get(fileRoot, "avatar").toAbsolutePath();
            if(!FileUtil.exists(path,false)){
                FileUtil.mkdir(path);
            }
            //上传文件
            String pathStr = path.toString();
            String originalFilename = file.getOriginalFilename();
            if(!StringUtils.hasText(originalFilename)){
                return PageResult.err().msg("文件不能为空！");
            }
            String fileName = getUniqueFileName(originalFilename,user.getLoginName());
            if(!StringUtils.hasText(fileName)){
                return PageResult.err().msg("系统不支持的图片格式！");
            }
//            String newFileName = pathStr+"/"+fileName;
            // 创建临时文件
            File tempFile = File.createTempFile("temp", null);
            // 将MultipartFile对象转换为File对象
            file.transferTo(tempFile);
            // 重命名文件
            File renamedFile = new File(pathStr, fileName);
            FileUtil.copy(tempFile,renamedFile,true);
            FileUtil.del(tempFile);
            //将文件名和文件路径存入表中
            // 用户修改
            User entity = userService.getEntity(userId);
            entity.setAvatarUrl("avatar/"+fileName);
            entity.setId(getCurUser().getId());
            userService.update(entity);
            return PageResultEx.ok().data(fileRootUrl+"avatar/"+fileName+"?"+new Date().getTime());
        } catch (MyException e) {
            return PageResultEx.err().msg("系统不支持的图片格式");
        } catch (Exception e) {
            return PageResultEx.err().msg("系统不支持的图片格式");
        }
    }

    private static String getUniqueFileName(String fileName,String ID) {
        //获取文件后缀名并转化为小写，用于后续比较
        String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()).toLowerCase();
        //创建图片类型数组
        String img[] = {"jpg", "jpeg", "png"};
        for(int i = 0; i < img.length; i++){
            if (img[i].equals(fileType)) {
                String extension = fileName.substring(fileName.lastIndexOf('.'));
//                String uniqueID = UUID.randomUUID().toString();
                return ID + extension;
            }
        }
        return null;
    }

}
